package main

import (
	"net"
	"strings"
)

const (
	WhoIsOnline string = "users"
	Rename      string = "rename"
	ChatTo      string = "to"
)

type User struct {
	Name   string
	Addr   string
	C      chan string
	IsLive chan bool
	conn   net.Conn
	server *Server
}

func (user *User) Online() {
	user.server.broadCast(user, user.Name+"已经上线")
	user.server.mapLock.Lock()
	user.server.OnlineMap[user.Name] = user
	user.server.mapLock.Unlock()
}

func (user *User) Offline() {
	user.server.mapLock.Lock()
	delete(user.server.OnlineMap, user.Name)
	user.server.mapLock.Unlock()
	user.server.broadCast(user, user.Name+"已经下线")
}

func (user *User) HandleMessage(msg string) {
	split := strings.Split(msg, "|")
	cmd := split[0]
	switch cmd {
	case WhoIsOnline:
		for _, u := range user.server.OnlineMap {
			user.sendMsg(u.Name + ":在线\n")
		}
	case Rename:
		if len(split) != 2 {
			user.sendMsg("请输入正确的命令格式, 如 rename|zhangsan\n")
		} else {
			newName := split[1]
			user.rename(newName)
		}
	case ChatTo:
		if len(split) != 3 {
			user.sendMsg("请输入正确的命令格式, 如  to|zhangsan|hello\n")
			return
		}
		toUser := split[1]
		content := split[2]
		if toUser == "" || content == "" {
			user.sendMsg("请输入正确的消息格式, 如  to|zhangsan|hello\n")
			return
		}

		if to, ok := user.server.OnlineMap[toUser]; ok {
			to.sendMsg(user.Name + "对你说： " + content + "\n")
		} else {
			user.sendMsg("用户" + toUser + "不存在\n")
		}
	default:
		if len(msg) > 0 {
			user.BroadCast(msg)
		}
	}
}

func (user *User) rename(newName string) {
	if _, exist := user.server.OnlineMap[newName]; exist {
		user.sendMsg(newName + "已存在\n")
	} else {
		user.server.mapLock.Lock()
		delete(user.server.OnlineMap, user.Name)
		user.server.OnlineMap[newName] = user
		user.server.mapLock.Unlock()
		user.Name = newName
		user.sendMsg("名称已更新为：" + newName + "\n")
	}
}

func (user *User) sendMsg(msg string) {
	user.conn.Write([]byte(msg))
}

func (user *User) BroadCast(msg string) {
	user.server.broadCast(user, user.Name+":"+msg)
}

func (u *User) ListenMessage() {
	for {
		// 循环监听 有消息写到客户端中
		msg := <-u.C
		u.conn.Write([]byte(msg + "\n"))
	}
}

func (user *User) ForceOffline() {
	user.sendMsg("超时，强制下线\n")
	user.Offline()
	close(user.C)
	close(user.IsLive)
}

func NewUser(conn net.Conn, s *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		C:      make(chan string),
		IsLive: make(chan bool),
		conn:   conn,
		server: s,
	}
	go user.ListenMessage()
	return user
}
